3 void elf_init(struct elf_params_t
*params
)
5 params
->has_start_addr
= false;
6 params
->start_addr
= 0;
7 params
->first_section
= NULL
;
8 params
->last_section
= NULL
;
11 extern void *xmalloc(size_t s
);
13 static struct elf_section_t
*elf_add_section(struct elf_params_t
*params
)
15 struct elf_section_t
*sec
= xmalloc(sizeof(struct elf_section_t
));
16 if(params
->first_section
== NULL
)
17 params
->first_section
= params
->last_section
= sec
;
20 params
->last_section
->next
= sec
;
21 params
->last_section
= sec
;
28 void elf_add_load_section(struct elf_params_t
*params
,
29 uint32_t load_addr
, uint32_t size
, const void *section
)
31 struct elf_section_t
*sec
= elf_add_section(params
);
34 sec
->addr
= load_addr
;
36 sec
->section
= xmalloc(size
);
37 memcpy(sec
->section
, section
, size
);
40 void elf_add_fill_section(struct elf_params_t
*params
,
41 uint32_t fill_addr
, uint32_t size
, uint32_t pattern
)
45 printf("oops, non-zero filling, ignore fill section\n");
49 struct elf_section_t
*sec
= elf_add_section(params
);
52 sec
->addr
= fill_addr
;
54 sec
->pattern
= pattern
;
57 void elf_output(struct elf_params_t
*params
, elf_write_fn_t write
, void *user
)
60 uint32_t phoff
= sizeof(Elf32_Ehdr
);
61 uint32_t phentsize
= sizeof(Elf32_Phdr
);
63 uint32_t shstrndx
= SHN_UNDEF
;
64 struct elf_section_t
*sec
= params
->first_section
;
70 if(sec
->type
== EST_LOAD
)
80 memset(&ehdr
, 0, EI_NIDENT
);
81 ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
82 ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
83 ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
84 ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
85 ehdr
.e_ident
[EI_CLASS
] = ELFCLASS32
;
86 ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
87 ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
88 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
89 ehdr
.e_ident
[EI_ABIVERSION
] = 0;
90 ehdr
.e_type
= ET_EXEC
;
91 ehdr
.e_machine
= EM_ARM
;
92 ehdr
.e_version
= EV_CURRENT
;
93 ehdr
.e_entry
= params
->start_addr
;
97 if(params
->has_start_addr
)
98 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
99 ehdr
.e_ehsize
= sizeof ehdr
;
100 ehdr
.e_phentsize
= phentsize
;
101 ehdr
.e_phnum
= phnum
;
102 ehdr
.e_shentsize
= 0;
104 ehdr
.e_shstrndx
= shstrndx
;
106 write(user
, 0, &ehdr
, sizeof ehdr
);
108 sec
= params
->first_section
;
112 sec
->offset
+= phoff
+ phnum
* phentsize
;
114 phdr
.p_type
= PT_LOAD
;
115 if(sec
->type
== EST_LOAD
)
116 phdr
.p_offset
= sec
->offset
;
119 phdr
.p_paddr
= sec
->addr
;
120 phdr
.p_vaddr
= phdr
.p_paddr
; /* assume identity map ? */
121 phdr
.p_memsz
= sec
->size
;
122 if(sec
->type
== EST_LOAD
)
123 phdr
.p_filesz
= phdr
.p_memsz
;
126 phdr
.p_flags
= PF_X
| PF_W
| PF_R
;
129 write(user
, offset
, &phdr
, sizeof phdr
);
131 offset
+= sizeof(Elf32_Phdr
);
135 sec
= params
->first_section
;
138 if(sec
->type
== EST_LOAD
)
139 write(user
, sec
->offset
, sec
->section
, sec
->size
);
144 bool elf_is_empty(struct elf_params_t
*params
)
146 return params
->first_section
== NULL
;
149 void elf_set_start_addr(struct elf_params_t
*params
, uint32_t addr
)
151 params
->has_start_addr
= true;
152 params
->start_addr
= addr
;
155 void elf_release(struct elf_params_t
*params
)
157 struct elf_section_t
*sec
, *next_sec
;
158 sec
= params
->first_section
;
161 next_sec
= sec
->next
;
162 if(sec
->type
== EST_LOAD
)
167 params
->first_section
= NULL
;
168 params
->last_section
= NULL
;