| 199 | | char[] sectionName = getNameString(shnames, thisSection.sh_name); |
|---|
| 200 | | |
|---|
| 201 | | sectionLookup[sectionName] = thisSection; |
|---|
| 202 | | |
|---|
| 203 | | //NOTE: section names and types expanded for debugging and development purposes |
|---|
| 204 | | //NOTE: these can probably be reduced down to a minimal set once the data in each section |
|---|
| 205 | | //NOTE: can be handled and accounted for either in the symbol table and/or relocations data. |
|---|
| 206 | | //TODO: reduce this monster switch |
|---|
| 207 | | switch(sectionName){ |
|---|
| 208 | | case ".bss": |
|---|
| 209 | | /* This section holds uninitialized data that contribute to the program's memory image. By |
|---|
| 210 | | definition, the system initializes the data with zeros when the program begins to run. The |
|---|
| 211 | | section occupies no file space, as indicated by the section type, SHT_NOBITS.*/ |
|---|
| 212 | | break; |
|---|
| 213 | | case ".comment": |
|---|
| 214 | | /* This section holds version control information. */ |
|---|
| 215 | | break; |
|---|
| 216 | | case ".data": |
|---|
| 217 | | case ".data1": |
|---|
| 218 | | /* These sections hold initialized data that contribute to the program's memory image. */ |
|---|
| 219 | | break; |
|---|
| 220 | | case ".debug": |
|---|
| 221 | | /* This section holds information for symbolic debugging. The contents are unspecified. */ |
|---|
| 222 | | break; |
|---|
| 223 | | case ".dynamic": |
|---|
| 224 | | /* This section holds dynamic linking information. The section's attributes will include the |
|---|
| 225 | | SHF_ALLOC bit. Whether the SHF_WRITE bit is set is processor specific. */ |
|---|
| 226 | | break; |
|---|
| 227 | | |
|---|
| 228 | | case ".dynstr": |
|---|
| 229 | | /* This section holds strings needed for dynamic linking, most commonly the strings that |
|---|
| 230 | | represent the names associated with symbol table entries. */ |
|---|
| 231 | | reader.setPosition(thisSection.sh_offset); |
|---|
| 232 | | reader.get(dynsymnames,thisSection.sh_size); |
|---|
| 233 | | break; |
|---|
| 234 | | |
|---|
| 235 | | case ".dynsym": |
|---|
| 236 | | /* This section holds the dynamic linking symbol table, as "Symbol Table" describes. */ |
|---|
| 237 | | dynamic = true; |
|---|
| 238 | | symtableidx = i; |
|---|
| 239 | | break; |
|---|
| 240 | | |
|---|
| 241 | | case ".fini": |
|---|
| 242 | | /* This section holds executable instructions that contribute to the process termination code. |
|---|
| 243 | | That is, when a program exits normally, the system arranges to execute the code in this |
|---|
| 244 | | section. */ |
|---|
| 245 | | break; |
|---|
| 246 | | case ".got": |
|---|
| 247 | | /* This section holds the global offset table. */ |
|---|
| 248 | | break; |
|---|
| 249 | | case ".hash": |
|---|
| 250 | | /* This section holds a symbol hash table. */ |
|---|
| 251 | | break; |
|---|
| 252 | | case ".init": |
|---|
| 253 | | /* This section holds executable instructions that contribute to the process initialization code. |
|---|
| 254 | | That is, when a program starts to run, the system arranges to execute the code in this section |
|---|
| 255 | | before calling the main program entry point (called main for C programs). */ |
|---|
| 256 | | break; |
|---|
| 257 | | case ".interp": |
|---|
| 258 | | /* This section holds the path name of a program interpreter. If the file has a loadable segment |
|---|
| 259 | | that includes the section, the section's attributes will include the SHF_ALLOC bit; otherwise, |
|---|
| 260 | | that bit will be off. */ |
|---|
| 261 | | break; |
|---|
| 262 | | case ".line": |
|---|
| 263 | | /* This section holds line number information for symbolic debugging, which describes the |
|---|
| 264 | | correspondence between the source program and the machine code. The contents are |
|---|
| 265 | | unspecified. */ |
|---|
| 266 | | break; |
|---|
| 267 | | case ".note": |
|---|
| 268 | | /* This section holds information in the format for the "Note Section" */ |
|---|
| 269 | | break; |
|---|
| 270 | | case ".plt": |
|---|
| 271 | | /* This section holds the procedure linkage table. */ |
|---|
| 272 | | break; |
|---|
| 273 | | case ".rodata": |
|---|
| 274 | | case ".rodata1": |
|---|
| 275 | | /* These sections hold read-only data that typically contribute to a non-writable segment in |
|---|
| 276 | | the process image. */ |
|---|
| 277 | | break; |
|---|
| 278 | | case ".shstrtab": |
|---|
| 279 | | /* This section holds section names. */ |
|---|
| 280 | | break; |
|---|
| 281 | | |
|---|
| 282 | | case ".strtab": |
|---|
| 283 | | /* This section holds strings, most commonly the strings that represent the names associated |
|---|
| 284 | | with symbol table entries. If the file has a loadable segment that includes the symbol string |
|---|
| 285 | | table, the section's attributes will include the SHF_ALLOC bit; otherwise, that bit will be off. */ |
|---|
| 286 | | reader.setPosition(thisSection.sh_offset); |
|---|
| 287 | | reader.get(symtabnames,thisSection.sh_size); |
|---|
| 288 | | break; |
|---|
| 289 | | |
|---|
| 290 | | case ".symtab": |
|---|
| 291 | | /* This section holds a symbol table, as "Symbol Table" in this section describes. If the file |
|---|
| 292 | | has a loadable segment that includes the symbol table, the section's attributes will include |
|---|
| 293 | | the SHF_ALLOC bit; otherwise, that bit will be off. */ |
|---|
| 294 | | |
|---|
| 295 | | //loadStaticSymbols(thisSection.sh_offset,thisSection.sh_size); |
|---|
| 296 | | |
|---|
| 297 | | dynamic = false; |
|---|
| 298 | | symtableidx = i; |
|---|
| 299 | | break; |
|---|
| 300 | | |
|---|
| 301 | | case ".text": |
|---|
| 302 | | /* This section holds the "text," or executable instructions, of a program. */ |
|---|
| 303 | | break; |
|---|
| 304 | | default: |
|---|
| 305 | | /* .relname and .relaname |
|---|
| 306 | | These sections hold relocation information, as "Relocation" below describes. If the file has |
|---|
| 307 | | a loadable segment that includes relocation, the sections' attributes will include the |
|---|
| 308 | | SHF_ALLOC bit; otherwise, that bit will be off. Conventionally, name is supplied by the |
|---|
| 309 | | section to which the relocations apply. Thus a relocation section for .text normally |
|---|
| 310 | | would have the name .rel.text or .rela.text. */ |
|---|
| 311 | | |
|---|
| 312 | | if(sectionName.length >= 6 && sectionName[0..6] == ".rela."){ |
|---|
| 313 | | char[] relocatedName = sectionName[6..$]; |
|---|
| 314 | | Elf32_Rela rel; |
|---|
| 315 | | } |
|---|
| 316 | | else if(sectionName.length >= 5 && sectionName[0..5] == ".rel."){ |
|---|
| 317 | | char[] relocatedName = sectionName[5..$]; |
|---|
| 318 | | Elf32_Rel rel; |
|---|
| 319 | | } |
|---|
| 320 | | else{ |
|---|
| 321 | | //TODO: treat the section as it's own symbol perhaps? (e.g. gnu.linkonce.t) |
|---|
| 322 | | } |
|---|
| 323 | | break; |
|---|
| 324 | | } |
|---|
| | 202 | |
|---|
| | 203 | switch(thisSection.sh_type){ |
|---|
| | 204 | case SHT_NULL: |
|---|
| | 205 | /*This value marks the section header as inactive; it does not have an associated section. |
|---|
| | 206 | Other members of the section header have undefined values */ |
|---|
| | 207 | break; |
|---|
| | 208 | |
|---|
| | 209 | case SHT_PROGBITS: |
|---|
| | 210 | /*The section holds information defined by the program, whose format and meaning are |
|---|
| | 211 | determined solely by the program.*/ |
|---|
| | 212 | break; |
|---|
| | 213 | |
|---|
| | 214 | case SHT_SYMTAB: |
|---|
| | 215 | /* symbol table */ |
|---|
| | 216 | // get associated string table |
|---|
| | 217 | Elf32_Shdr stringSection = sechdrs[thisSection.sh_link]; |
|---|
| | 218 | char[] stringTable; |
|---|
| | 219 | |
|---|
| | 220 | reader.setPosition(stringSection.sh_offset); |
|---|
| | 221 | reader.get(stringTable,stringSection.sh_size); |
|---|
| | 222 | |
|---|
| | 223 | char[][] symbolNames = crackStringTable(stringTable); |
|---|
| | 224 | |
|---|
| | 225 | // read in the symbols |
|---|
| | 226 | reader.setPosition(thisSection.sh_offset); |
|---|
| | 227 | parseSYMTAB(thisSection.sh_info, symbolNames, reader); |
|---|
| | 228 | break; |
|---|
| | 229 | |
|---|
| | 230 | case SHT_STRTAB: |
|---|
| | 231 | /*The section holds a string table. An object file may have multiple string table sections. */ |
|---|
| | 232 | break; |
|---|
| | 233 | |
|---|
| | 234 | case SHT_RELA: |
|---|
| | 235 | /*The section holds relocation entries with explicit addends, such as type Elf32_Rela |
|---|
| | 236 | for the 32-bit class of object files. An object file may have multiple relocation sections.*/ |
|---|
| | 237 | break; |
|---|
| | 238 | |
|---|
| | 239 | case SHT_HASH: break; |
|---|
| | 240 | case SHT_DYNAMIC: break; |
|---|
| | 241 | |
|---|
| | 242 | case SHT_NOTE: |
|---|
| | 243 | /*The section holds information that marks the file in some way. |
|---|
| | 244 | See "Note Section" in Part 2 for details.*/ |
|---|
| | 245 | |
|---|
| | 246 | break; |
|---|
| | 247 | |
|---|
| | 248 | case SHT_NOBITS: break; |
|---|
| | 249 | case SHT_REL: |
|---|
| | 250 | /* The section holds relocation entries without explicit addends, such as type |
|---|
| | 251 | Elf32_Rel for the 32-bit class of object files. An object file may have multiple relocation |
|---|
| | 252 | sections. */ |
|---|
| | 253 | break; |
|---|
| | 254 | |
|---|
| | 255 | case SHT_SHLIB: break; |
|---|
| | 256 | case SHT_DYNSYM: break; |
|---|
| | 257 | case SHT_LOPROC: break; |
|---|
| | 258 | case SHT_HIPROC: break; |
|---|
| | 259 | case SHT_LOUSER: break; |
|---|
| | 260 | case SHT_HIUSER: break; |
|---|
| | 261 | default: |
|---|
| | 262 | } |
|---|
| 328 | | |
|---|
| 329 | | protected char[] getNameString(char [] tab, uint pos){ |
|---|
| 330 | | assert(pos < tab.length); |
|---|
| 331 | | int i = pos; |
|---|
| 332 | | while(tab[i] != '\0'){ |
|---|
| 333 | | i++; |
|---|
| 334 | | } |
|---|
| 335 | | debug debugLog("\tgetNameString: %s",tab[pos..i]); |
|---|
| 336 | | return tab[pos..i]; |
|---|
| 337 | | } |
|---|
| 338 | | |
|---|
| 339 | | protected void loadSymTable(uint secnum, ELFReader reader){ |
|---|
| 340 | | assert(sechdrs[secnum].sh_entsize > 0); |
|---|
| 341 | | reader.setPosition(sechdrs[secnum].sh_offset); |
|---|
| 342 | | |
|---|
| 343 | | // TODO: Probably NOT put all symbols at the same place |
|---|
| 344 | | symbols.length = sechdrs[secnum].sh_size / sechdrs[secnum].sh_entsize; |
|---|
| 345 | | for(int i = 0; i < symbols.length; i++){ |
|---|
| 346 | | Elf32_Sym symbol; |
|---|
| 347 | | reader.get(symbol); |
|---|
| 348 | | symbols[i] = symbol; |
|---|
| 349 | | // debug debugLog("symbol: %s",symbol.st.name |
|---|
| 350 | | } |
|---|
| | 266 | |
|---|
| | 267 | protected char[][] crackStringTable(char[] data){ |
|---|
| | 268 | char[][] table; |
|---|
| | 269 | for(uint i = 0, last = 0; i<data.length; i++){ |
|---|
| | 270 | if(data[i] == '\0'){ |
|---|
| | 271 | table ~= data[last..i]; |
|---|
| | 272 | i++; |
|---|
| | 273 | last = i; |
|---|
| | 274 | } |
|---|
| | 275 | } |
|---|
| | 276 | return table; |
|---|
| | 277 | } |
|---|
| | 278 | |
|---|
| | 279 | protected void loadSymTable(uint idx, ELFReader reader) { |
|---|
| | 280 | |
|---|
| | 281 | } |
|---|
| | 282 | |
|---|
| | 283 | protected void parseSYMTAB(uint symbols, char[][] symbolNames, |
|---|
| | 284 | ELFReader reader){ |
|---|
| | 285 | for(int i=0; i<symbols; i++){ |
|---|
| | 286 | Elf32_Sym sym; |
|---|
| | 287 | reader.get(sym); |
|---|
| | 288 | |
|---|
| | 289 | //TODO: refer to STB_LOCAL to ensure that symbols don't overlap |
|---|
| | 290 | |
|---|
| | 291 | ExportSymbol exportSym; |
|---|
| | 292 | exportSym.name = symbolNames[sym.st_name]; |
|---|
| | 293 | |
|---|
| | 294 | //TODO: resolve symbol data address by cracking the sym fields per the specification |
|---|
| | 295 | } |
|---|