Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
troll-rs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
2xs
The Pip protokernel
troll-rs
Commits
e3b0e81f
Commit
e3b0e81f
authored
1 year ago
by
Michael Hauspie
Browse files
Options
Downloads
Patches
Plain Diff
Add pip elf export
parent
ddcd1374
No related branches found
No related tags found
1 merge request
!1
Add a new `link` subcommand
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/link.rs
+81
-17
81 additions, 17 deletions
src/link.rs
with
81 additions
and
17 deletions
src/link.rs
+
81
−
17
View file @
e3b0e81f
...
@@ -12,17 +12,20 @@
...
@@ -12,17 +12,20 @@
//! generates a binary that includes Pip MPU and the user code as root
//! generates a binary that includes Pip MPU and the user code as root
//! partition
//! partition
use
anyhow
::{
anyhow
,
Result
};
use
anyhow
::
Result
;
use
clap
::
Parser
;
use
clap
::
Parser
;
use
elf
::
endian
::
AnyEndian
;
use
elf
::
endian
::
AnyEndian
;
use
std
::
path
::
PathBuf
;
use
std
::
path
::
PathBuf
;
use
pip_mpu_relocate
::
reloc
::
RelIter
;
//
use pip_mpu_relocate::reloc::RelIter;
use
pip_mpu_relocate
::
relocate
::
relocate
;
//
use pip_mpu_relocate::relocate::relocate;
use
pip_mpu_relocate
::
symbols
::
SymbolsQuery
;
//
use pip_mpu_relocate::symbols::SymbolsQuery;
use
std
::
io
::
Write
;
use
std
::
io
::
Write
;
const
PADDING_SIZE
:
usize
=
32
;
const
PADDING_BUFFER
:
[
u8
;
PADDING_SIZE
]
=
[
0xff
;
PADDING_SIZE
];
const
PIP_EXPORT_SECTIONS
:
&
'static
[
&
str
]
=
&
[
".vector_table"
,
".text"
,
".data"
];
/// Options for the link subcommand
/// Options for the link subcommand
#[derive(Parser,
Debug)]
#[derive(Parser,
Debug)]
pub
struct
Opts
{
pub
struct
Opts
{
...
@@ -37,29 +40,56 @@ pub struct Opts {
...
@@ -37,29 +40,56 @@ pub struct Opts {
/// Path the Pipcore MPU elf file
/// Path the Pipcore MPU elf file
#[arg(long,
short)]
#[arg(long,
short)]
pip_elf
:
Option
<
PathBuf
>
pip_elf
:
Option
<
PathBuf
>
,
}
/// Dump the binary content of the given sections to the output file.
///
/// It returns the number of bytes writen
fn
dump_sections
<
's
,
T
:
Write
>
(
elf
:
&
elf
::
ElfBytes
<
AnyEndian
>
,
section_names
:
&
[
&
str
],
output
:
&
mut
T
,
)
->
Result
<
usize
>
{
let
mut
output_size
=
0
;
for
section_name
in
section_names
{
let
section
=
match
elf
.section_header_by_name
(
section_name
)
?
{
None
=>
return
Err
(
anyhow!
(
"Section {section_name} not found"
)),
Some
(
s
)
=>
s
,
};
let
(
bytes
,
compression
)
=
elf
.section_data
(
&
section
)
?
;
assert_eq!
(
compression
,
None
);
output
.write_all
(
bytes
)
?
;
output_size
+=
bytes
.len
();
}
Ok
(
output_size
)
}
}
pub
fn
link
(
opts
:
Opts
)
->
Result
<
()
>
{
fn
align
(
value
:
usize
,
align
:
usize
)
->
usize
{
let
a
=
value
&
(
align
-
1
);
if
a
==
0
{
0
}
else
{
align
-
a
}
}
pub
fn
link
(
opts
:
Opts
)
->
Result
<
()
>
{
// First, open and parse both crt0 and user_code elf files
// First, open and parse both crt0 and user_code elf files
let
crt0_elf_file
=
std
::
fs
::
read
(
&
opts
.crt0_elf
)
?
;
let
crt0_elf_file
=
std
::
fs
::
read
(
&
opts
.crt0_elf
)
?
;
let
crt0_elf_data
=
crt0_elf_file
.as_slice
();
let
crt0_elf_data
=
crt0_elf_file
.as_slice
();
let
crt0_elf
=
elf
::
ElfBytes
::
<
AnyEndian
>
::
minimal_parse
(
crt0_elf_data
)
?
;
let
_
crt0_elf
=
elf
::
ElfBytes
::
<
AnyEndian
>
::
minimal_parse
(
crt0_elf_data
)
?
;
let
user_code_elf_file
=
std
::
fs
::
read
(
&
opts
.user_code_elf
)
?
;
let
user_code_elf_file
=
std
::
fs
::
read
(
&
opts
.user_code_elf
)
?
;
let
user_code_elf_data
=
user_code_elf_file
.as_slice
();
let
user_code_elf_data
=
user_code_elf_file
.as_slice
();
let
user_code_elf
=
elf
::
ElfBytes
::
<
AnyEndian
>
::
minimal_parse
(
user_code_elf_data
)
?
;
let
_user_code_elf
=
elf
::
ElfBytes
::
<
AnyEndian
>
::
minimal_parse
(
user_code_elf_data
)
?
;
// Then open Pip elf file if necessary
// Then open Pip elf file if necessary
let
pip_elf_data
=
match
opts
.pip_elf
{
let
pip_elf_data
=
match
opts
.pip_elf
{
None
=>
None
,
None
=>
None
,
Some
(
pip_path
)
=>
{
Some
(
pip_path
)
=>
Some
(
std
::
fs
::
read
(
&
pip_path
)
?
),
Some
(
std
::
fs
::
read
(
&
pip_path
)
?
)
}
};
};
let
pip_elf
=
match
pip_elf_data
{
let
pip_elf
=
match
pip_elf_data
{
...
@@ -69,7 +99,41 @@ pub fn link(opts: Opts) -> Result<()> {
...
@@ -69,7 +99,41 @@ pub fn link(opts: Opts) -> Result<()> {
// When reaching here, all files were opened and parsed
// When reaching here, all files were opened and parsed
// we can safely open the output file
// we can safely open the output file
let
mut
output
=
std
::
fs
::
File
::
create
(
opts
.output
)
?
;
let
mut
output
=
std
::
fs
::
File
::
create
(
opts
.output
)
?
;
writeln!
(
output
,
"Yeah it works"
)
?
;
// First, if needed, output pip binary, padded to 32 bytes
if
let
Some
(
pip_elf
)
=
pip_elf
{
let
output_size
=
dump_sections
(
&
pip_elf
,
PIP_EXPORT_SECTIONS
,
&
mut
output
)
?
;
// If ouput size is not align on configured padding size bytes, add some padding
let
pad_bytes
=
align
(
output_size
,
PADDING_SIZE
);
if
pad_bytes
>
0
{
output
.write_all
(
&
PADDING_BUFFER
[
0
..
pad_bytes
])
?
;
}
}
Ok
(())
Ok
(())
}
}
#[cfg(test)]
mod
tests
{
use
super
::
align
;
#[test]
fn
test_align
()
{
assert_eq!
(
align
(
0
,
8
),
0
);
assert_eq!
(
align
(
1
,
8
),
7
);
assert_eq!
(
align
(
2
,
8
),
6
);
assert_eq!
(
align
(
3
,
8
),
5
);
assert_eq!
(
align
(
4
,
8
),
4
);
assert_eq!
(
align
(
5
,
8
),
3
);
assert_eq!
(
align
(
6
,
8
),
2
);
assert_eq!
(
align
(
7
,
8
),
1
);
assert_eq!
(
align
(
8
,
8
),
0
);
assert_eq!
(
align
(
9
,
8
),
7
);
assert_eq!
(
align
(
10
,
8
),
6
);
assert_eq!
(
align
(
11
,
8
),
5
);
assert_eq!
(
align
(
12
,
8
),
4
);
assert_eq!
(
align
(
13
,
8
),
3
);
assert_eq!
(
align
(
14
,
8
),
2
);
assert_eq!
(
align
(
15
,
8
),
1
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment