@@ -72,13 +72,23 @@ void ElfAnalyzer::gatherInfoFromElf(
7272 {
7373 if (p->sourceType == PatchSourceType::Section)
7474 {
75- std::string_view nameAsLabel = std::string_view (p->symbol ).substr (1 );
76- if (nameAsLabel == symbolName)
77- {
78- p->srcAddress = symbol.st_value ;
79- p->sectionIdx = symbol.st_shndx ;
80- p->symbol = nameAsLabel;
81- }
75+ if (p->isNcpSet )
76+ {
77+ if (p->symbol == symbolName)
78+ {
79+ p->sectionIdx = symbol.st_shndx ;
80+ }
81+ }
82+ else
83+ {
84+ std::string_view nameAsLabel = std::string_view (p->symbol ).substr (1 );
85+ if (nameAsLabel == symbolName)
86+ {
87+ p->srcAddress = symbol.st_value ;
88+ p->sectionIdx = symbol.st_shndx ;
89+ p->symbol = nameAsLabel;
90+ }
91+ }
8292 }
8393 else
8494 {
@@ -125,34 +135,26 @@ void ElfAnalyzer::gatherInfoFromElf(
125135 }
126136 if (sectionName.starts_with (" .ncp_set" ))
127137 {
128- // found the ncp_set section, get all hook definitions stored there
129-
130- int srcAddrOv = -1 ;
131- if (sectionName.length () != 8 && sectionName.substr (8 ).starts_with (" _ov" ))
132- {
133- try {
134- srcAddrOv = std::stoi (std::string (sectionName.substr (11 )));
135- } catch (std::exception& e) {
136- Log::out << OWARN << " Found invalid overlay reading ncp_set section: " << sectionName << std::endl;
137- return false ;
138- }
139- }
140-
138+ // Handle ncp_set sections directly - each section corresponds to a specific patch
141139 const char * sectionData = m_elf->getSection <char >(section);
142-
140+
141+ // Find the patch that corresponds to this section
143142 for (auto & p : patchInfo)
144143 {
145- if (p->isNcpSet && p->srcAddressOv == srcAddrOv )
144+ if (p->isNcpSet && p->symbol == sectionName )
146145 {
147- u32 dataOffset = p->srcAddress - section.sh_addr ;
148- if (dataOffset + 4 > section.sh_size )
146+ if (section.sh_size != 4 )
149147 {
150148 std::ostringstream oss;
151- oss << " Tried to read " << OSTR (sectionName) << " data out of bounds ." ;
149+ oss << " ncp_set section " << OSTR (sectionName) << " should be exactly 4 bytes, but is " << section. sh_size << " bytes ." ;
152150 throw ncp::exception (oss.str ());
153151 }
152+
153+ // Read the function pointer from the section data
154154 // ncp_set comes with the THUMB bit, we must clear it!
155- p->srcAddress = Util::read<u32 >(§ionData[dataOffset]) & ~1 ;
155+ p->srcAddress = Util::read<u32 >(§ionData[0 ]) & ~1 ;
156+ // Also determine if the source function is thumb from the LSB
157+ p->srcThumb = bool (Util::read<u32 >(§ionData[0 ]) & 1 );
156158 }
157159 }
158160 }
@@ -213,12 +215,14 @@ void ElfAnalyzer::gatherInfoFromElf(
213215
214216 if (ncp::Application::isVerbose (ncp::VerboseTag::Patch))
215217 {
216- Log::out << ANSI_bCYAN " Patches:" ANSI_RESET " \n "
217- << ANSI_bWHITE " SRC_ADDR" ANSI_RESET " "
218- << ANSI_bWHITE " SRC_ADDR_OV" ANSI_RESET " "
218+ Log::out << ANSI_bCYAN " Patches (post-ELF analysis):" ANSI_RESET " \n "
219+ << ANSI_bYELLOW " Note: Fields marked with * are populated/updated during ELF analysis phase" ANSI_RESET << std::endl;
220+
221+ Log::out << ANSI_bWHITE " SRC_ADDR" ANSI_RESET " "
222+ << ANSI_bWHITE " SRC_ADDR_OV" ANSI_RESET " "
219223 << ANSI_bWHITE " DST_ADDR" ANSI_RESET " "
220224 << ANSI_bWHITE " DST_ADDR_OV" ANSI_RESET " "
221- << ANSI_bWHITE " PATCH_TYPE" ANSI_RESET " "
225+ << ANSI_bWHITE " PATCH_TYPE" ANSI_RESET " "
222226 << ANSI_bWHITE " SEC_IDX" ANSI_RESET " "
223227 << ANSI_bWHITE " SEC_SIZE" ANSI_RESET " "
224228 << ANSI_bWHITE " NCP_SET" ANSI_RESET " "
@@ -228,26 +232,28 @@ void ElfAnalyzer::gatherInfoFromElf(
228232 << ANSI_bWHITE " SYMBOL" ANSI_RESET << std::endl;
229233 for (auto & p : patchInfo)
230234 {
231- std::string sourceTypeStr;
232- switch (p->sourceType ) {
233- case PatchSourceType::Section: sourceTypeStr = " section" ; break ;
234- case PatchSourceType::Label: sourceTypeStr = " label" ; break ;
235- case PatchSourceType::Symver: sourceTypeStr = " symver" ; break ;
236- }
235+ if (ncp::Application::isVerbose (ncp::VerboseTag::NoLib) && p->unit ->getType () == core::CompilationUnitType::LibraryFile)
236+ continue ;
237237
238238 Log::out <<
239- ANSI_CYAN << std::setw (8 ) << std::hex << p->srcAddress << ANSI_RESET " " <<
239+ ANSI_CYAN << std::setw (10 ) << Util::intToAddr (p->srcAddress , 8 ) << " *" ;
240+ Log::out << ANSI_RESET " " <<
240241 ANSI_YELLOW << std::setw (11 ) << std::dec << p->srcAddressOv << ANSI_RESET " " <<
241- ANSI_BLUE << std::setw (8 ) << std::hex << p->destAddress << ANSI_RESET " " <<
242+ ANSI_BLUE << std::setw (8 ) << Util::intToAddr ( p->destAddress , 8 ) << ANSI_RESET " " <<
242243 ANSI_YELLOW << std::setw (11 ) << std::dec << p->destAddressOv << ANSI_RESET " " <<
243244 ANSI_MAGENTA << std::setw (10 ) << s_patchTypeNames[p->patchType ] << ANSI_RESET " " <<
244- ANSI_WHITE << std::setw (7 ) << std::dec << p->sectionIdx << ANSI_RESET " " <<
245+ ANSI_WHITE << std::setw (8 ) << std::dec << p->sectionIdx << " *" ;
246+ Log::out << ANSI_RESET " " <<
245247 ANSI_WHITE << std::setw (8 ) << std::dec << p->sectionSize << ANSI_RESET " " <<
246248 ANSI_GREEN << std::setw (7 ) << std::boolalpha << p->isNcpSet << ANSI_RESET " " <<
247- ANSI_GREEN << std::setw (9 ) << std::boolalpha << p->srcThumb << ANSI_RESET " " <<
249+ ANSI_GREEN << std::setw (9 ) << std::boolalpha << p->srcThumb ;
250+ // Mark srcThumb field populated during ELF analysis for ncp_set patches
251+ Log::out << (p->isNcpSet ? " *" : " " );
252+ Log::out << ANSI_RESET " " <<
248253 ANSI_GREEN << std::setw (9 ) << std::boolalpha << p->destThumb << ANSI_RESET " " <<
249- ANSI_bYELLOW << std::setw (11 ) << sourceTypeStr << ANSI_RESET " " <<
250- ANSI_WHITE << p->symbol << ANSI_RESET << std::endl;
254+ ANSI_bYELLOW << std::setw (11 ) << toString (p->sourceType ) << ANSI_RESET " " <<
255+ ANSI_WHITE << p->symbol ;
256+ Log::out << ANSI_RESET << std::endl;
251257 }
252258 }
253259
0 commit comments