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
)
61 struct elf_section_t
*sec
= params
->first_section
;
65 memset(&ehdr
, 0, EI_NIDENT
);
67 uint32_t bss_strtbl
= 0;
68 uint32_t text_strtbl
= bss_strtbl
+ strlen(".bss") + 1;
69 uint32_t strtbl_size
= text_strtbl
+ strlen(".text") + 1;
73 if(sec
->type
== EST_LOAD
)
83 uint32_t strtbl_offset
= offset
;
85 ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
86 ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
87 ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
88 ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
89 ehdr
.e_ident
[EI_CLASS
] = ELFCLASS32
;
90 ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
91 ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
92 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
93 ehdr
.e_ident
[EI_ABIVERSION
] = 0;
94 ehdr
.e_type
= ET_EXEC
;
95 ehdr
.e_machine
= EM_ARM
;
96 ehdr
.e_version
= EV_CURRENT
;
97 ehdr
.e_entry
= params
->start_addr
;
99 if(params
->has_start_addr
)
100 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
101 ehdr
.e_ehsize
= sizeof ehdr
;
102 ehdr
.e_phentsize
= sizeof phdr
;
103 ehdr
.e_phnum
= phnum
;
104 ehdr
.e_shentsize
= sizeof shdr
;
105 ehdr
.e_shnum
= phnum
+ 1;
106 ehdr
.e_shstrndx
= ehdr
.e_shnum
- 1;
107 ehdr
.e_phoff
= ehdr
.e_ehsize
;
108 ehdr
.e_shoff
= ehdr
.e_ehsize
+ ehdr
.e_phnum
* ehdr
.e_phentsize
;
110 write(user
, 0, &ehdr
, sizeof ehdr
);
112 uint32_t data_offset
= ehdr
.e_ehsize
+ ehdr
.e_phnum
* ehdr
.e_phentsize
+
113 ehdr
.e_shnum
* ehdr
.e_shentsize
;
115 sec
= params
->first_section
;
116 offset
= ehdr
.e_phoff
;
119 sec
->offset
+= data_offset
;
121 phdr
.p_type
= PT_LOAD
;
122 if(sec
->type
== EST_LOAD
)
123 phdr
.p_offset
= sec
->offset
;
126 phdr
.p_paddr
= sec
->addr
;
127 phdr
.p_vaddr
= phdr
.p_paddr
; /* assume identity map ? */
128 phdr
.p_memsz
= sec
->size
;
129 if(sec
->type
== EST_LOAD
)
130 phdr
.p_filesz
= phdr
.p_memsz
;
133 phdr
.p_flags
= PF_X
| PF_W
| PF_R
;
136 write(user
, offset
, &phdr
, sizeof phdr
);
138 offset
+= sizeof(Elf32_Phdr
);
142 sec
= params
->first_section
;
143 offset
= ehdr
.e_shoff
;
146 shdr
.sh_name
= text_strtbl
;
147 if(sec
->type
== EST_LOAD
)
148 shdr
.sh_type
= SHT_PROGBITS
;
150 shdr
.sh_type
= SHT_NOBITS
;
151 shdr
.sh_flags
= SHF_ALLOC
| SHF_EXECINSTR
;
152 shdr
.sh_addr
= sec
->addr
;
153 shdr
.sh_offset
= sec
->offset
;
154 shdr
.sh_size
= sec
->size
;
155 shdr
.sh_link
= SHN_UNDEF
;
157 shdr
.sh_addralign
= 1;
160 write(user
, offset
, &shdr
, sizeof shdr
);
162 offset
+= sizeof(Elf32_Shdr
);
167 shdr
.sh_name
= bss_strtbl
;
168 shdr
.sh_type
= SHT_STRTAB
;
171 shdr
.sh_offset
= strtbl_offset
+ data_offset
;
172 shdr
.sh_size
= strtbl_size
;
173 shdr
.sh_link
= SHN_UNDEF
;
175 shdr
.sh_addralign
= 1;
178 write(user
, offset
, &shdr
, sizeof shdr
);
180 offset
+= sizeof(Elf32_Shdr
);
183 sec
= params
->first_section
;
186 if(sec
->type
== EST_LOAD
)
187 write(user
, sec
->offset
, sec
->section
, sec
->size
);
191 write(user
, strtbl_offset
+ data_offset
, ".bss\0.text\0", strtbl_size
);
194 bool elf_is_empty(struct elf_params_t
*params
)
196 return params
->first_section
== NULL
;
199 void elf_set_start_addr(struct elf_params_t
*params
, uint32_t addr
)
201 params
->has_start_addr
= true;
202 params
->start_addr
= addr
;
205 void elf_release(struct elf_params_t
*params
)
207 struct elf_section_t
*sec
, *next_sec
;
208 sec
= params
->first_section
;
211 next_sec
= sec
->next
;
212 if(sec
->type
== EST_LOAD
)
217 params
->first_section
= NULL
;
218 params
->last_section
= NULL
;