MCPcopy Create free account
hub / github.com/N64Recomp/N64Recomp / read_sections

Function read_sections

src/elf.cpp:223–617  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

221}
222
223ELFIO::section* read_sections(N64Recomp::Context& context, ELFIO::section*& mdebug_section_out, const N64Recomp::ElfParsingConfig& elf_config, const ELFIO::elfio& elf_file) {
224 ELFIO::section* symtab_section = nullptr;
225 std::vector<SegmentEntry> segments{};
226 segments.resize(elf_file.segments.size());
227 bool has_reference_symbols = context.has_reference_symbols();
228
229 // Copy the data for each segment into the segment entry list
230 for (size_t segment_index = 0; segment_index < elf_file.segments.size(); segment_index++) {
231 const auto& segment = *elf_file.segments[segment_index];
232 segments[segment_index].data_offset = segment.get_offset();
233 segments[segment_index].physical_address = segment.get_physical_address();
234 segments[segment_index].memory_size = segment.get_file_size();
235 }
236
237 //// Sort the segments by physical address
238 //std::sort(segments.begin(), segments.end(),
239 // [](const SegmentEntry& lhs, const SegmentEntry& rhs) {
240 // return lhs.data_offset < rhs.data_offset;
241 // }
242 //);
243
244 std::unordered_map<std::string, ELFIO::section*> reloc_sections_by_name;
245 std::unordered_map<std::string, ELFIO::section*> bss_sections_by_name;
246
247 // First pass over the sections to find the load addresses and track the minimum load address value. This mimics the objcopy raw binary output behavior.
248 uint32_t min_load_address = (uint32_t)-1;
249 for (const auto& section : elf_file.sections) {
250 auto& section_out = context.sections[section->get_index()];
251 ELFIO::Elf_Word type = section->get_type();
252 ELFIO::Elf_Xword flags = section->get_flags();
253 ELFIO::Elf_Xword section_size = section->get_size();
254
255 // Check if this section will end up in the ROM. It must not be a nobits (NOLOAD) type, must have the alloc flag set and must have a nonzero size.
256 if (type != ELFIO::SHT_NOBITS && (flags & ELFIO::SHF_ALLOC) && section_size != 0) {
257 std::optional<size_t> segment_index = get_segment(segments, section_size, section->get_offset());
258 if (!segment_index.has_value()) {
259 fmt::print(stderr, "Could not find segment that section {} belongs to!\n", section->get_name());
260 return nullptr;
261 }
262
263 const SegmentEntry& segment = segments[segment_index.value()];
264 // Calculate the load address of the section based on that of the segment.
265 // This will get modified afterwards in the next pass to offset by the minimum load address.
266 section_out.rom_addr = segment.physical_address + (section->get_offset() - segment.data_offset);
267 // Track the minimum load address.
268 min_load_address = std::min(min_load_address, section_out.rom_addr);
269 }
270 else {
271 // Otherwise mark this section as having an invalid rom address
272 section_out.rom_addr = (uint32_t)-1;
273 }
274 }
275
276 // Iterate over every section to record rom addresses and find the symbol table
277 for (const auto& section : elf_file.sections) {
278 auto& section_out = context.sections[section->get_index()];
279 //fmt::print(" {}: {} @ 0x{:08X}, 0x{:08X}\n", section->get_index(), section->get_name(), section->get_address(), context.rom.size());
280 // Set the rom address of this section to the current accumulated ROM size

Callers 1

from_elf_fileMethod · 0.85

Calls 8

get_segmentFunction · 0.85
has_reference_symbolsMethod · 0.80
get_indexMethod · 0.80
get_nameMethod · 0.80
find_reference_symbolMethod · 0.80
byteswapFunction · 0.50

Tested by

no test coverage detected