@@ -141,45 +141,75 @@ bool ProcessAMDGPU::GetProcessInfo(ProcessInstanceInfo &proc_info) {
141141 return true ;
142142}
143143
144- static std::pair<std::string, std::pair< uint64_t , uint64_t >>
145- ParsePathname ( const std::string &pathname ) {
146- std:: string file_path;
147- uint64_t offset = 0 ;
148- uint64_t size = 0 ;
149-
150- // Find the position of #offset=
151- size_t offset_pos = pathname. find ( " #offset= " ) ;
152- if (offset_pos != std::string::npos) {
153- // Extract the file path (remove file:// prefix if present)
154- std::string path = pathname. substr ( 0 , offset_pos);
155- if (path. find ( " file:// " ) == 0 ) {
156- file_path = path. substr ( 7 ); // Remove "file://"
157- } else {
158- file_path = path ;
159- }
160-
161- // Extract offset
162- size_t size_pos = pathname. find ( " &size= " , offset_pos);
163- if (size_pos != std::string::npos) {
164- std::string offset_str =
165- pathname. substr (offset_pos + 8 , size_pos - (offset_pos + 8 ));
166- std::string size_str = pathname. substr (size_pos + 6 );
167-
168- offset = std::stoull (offset_str);
169- size = std::stoull (size_str );
144+ std::optional<lldb_private::GPUDynamicLoaderLibraryInfo>
145+ ParseLibraryInfo (llvm::StringRef lib_spec ) {
146+ // This function will parse the shared library string that AMDs GPU driver
147+ // sends to the debugger. The format is one of:
148+ // file://<path>#offset=<file-offset>&size=<file-size>
149+ // memory://<name>#offset=<image-addr>&size=<image-size>
150+ lldb_private::GPUDynamicLoaderLibraryInfo lib_info;
151+ lib_info. load = true ;
152+
153+ auto get_offset_and_size = [](llvm::StringRef &values,
154+ std::optional< uint64_t > &offset,
155+ std::optional< uint64_t > &size ) {
156+ offset = std:: nullopt ;
157+ size = std:: nullopt ;
158+ llvm::StringRef value ;
159+ uint64_t uint_value;
160+ std::tie (value, values) = values. split ( ' & ' );
161+ while (!value. empty ()) {
162+ if (value. consume_front ( " offset= " )) {
163+ if (!value. getAsInteger ( 0 , uint_value))
164+ offset = uint_value;
165+ } else if (value. consume_front ( " size= " )) {
166+ if (!value. getAsInteger ( 0 , uint_value))
167+ size = uint_value;
168+ }
169+ std::tie (value, values) = values. split ( ' & ' );
170170 }
171+ };
172+
173+ if (lib_spec.consume_front (" file://" )) {
174+ llvm::StringRef path, values;
175+ std::tie (path, values) = lib_spec.split (' #' );
176+ if (path.empty ())
177+ return std::nullopt ;
178+ get_offset_and_size (values, lib_info.file_offset , lib_info.file_size );
179+ } else if (lib_spec.consume_front (" memory://" )) {
180+ llvm::StringRef name, values;
181+ std::tie (name, values) = lib_spec.split (' #' );
182+ if (name.empty ())
183+ return std::nullopt ;
184+ lib_info.pathname = name.str ();
185+ get_offset_and_size (values, lib_info.native_memory_address ,
186+ lib_info.native_memory_size );
187+ // We must have a valid address and size for memory objects.
188+ if (!(lib_info.native_memory_address .has_value () &&
189+ lib_info.native_memory_size .has_value ()))
190+ return std::nullopt ;
171191 } else {
172- // No offset/size parameters, just return the path
173- if (pathname.find (" file://" ) == 0 ) {
174- file_path = pathname.substr (7 );
175- } else {
176- file_path = pathname;
177- }
192+ return std::nullopt ;
193+ }
194+ // TODO: do we need this expanding into a URL or is this for JSON?
195+ lib_info.pathname .clear ();
196+ for (char c : path) {
197+ if (c == ' #' )
198+ lib_info.pathname += " %23" ;
199+ else if (c == ' $' )
200+ lib_info.pathname += " %24" ;
201+ else if (c == ' }' )
202+ lib_info.pathname += " %7D" ;
203+ else if (c == ' &' )
204+ lib_info.pathname += " &" ;
205+ else
206+ lib_info.pathname += c;
178207 }
179208
180- return {file_path, {offset, size}} ;
209+ return lib_info ;
181210}
182211
212+
183213std::optional<GPUDynamicLoaderResponse>
184214ProcessAMDGPU::GetGPUDynamicLoaderLibraryInfos (
185215 const GPUDynamicLoaderArgs &args) {
@@ -196,36 +226,19 @@ ProcessAMDGPU::GetGPUDynamicLoaderLibraryInfos(
196226 // Convert each GPU module to an SVR4LibraryInfo object
197227 for (const auto &[addr, module ] : gpu_modules) {
198228 if (module .is_loaded ) {
199- auto file_components = ParsePathname (module .path );
200- std::string path;
201- for (char c : file_components.first ) {
202- if (c == ' #' )
203- path += " %23" ;
204- else if (c == ' $' )
205- path += " %24" ;
206- else if (c == ' }' )
207- path += " %7D" ;
208- else if (c == ' &' )
209- path += " &" ;
210- else
211- path += c;
229+ if (auto lib_info = ParseLibraryInfo (module .path )) {
230+ LLDB_LOGF (log,
231+ " ProcessAMDGPU::%s() adding library: path=%s, addr=0x%" PRIx64
232+ " , offset=%" PRIu64 " , size=%" PRIu64,
233+ __FUNCTION__, lib_info->pathname .c_str (),
234+ lib_info->load_address .value (), lib_info->file_offset .value (),
235+ lib_info->file_size .value ());
236+ response.library_infos .push_back (*lib_info);
237+ } else {
238+ LLDB_LOGF (log,
239+ " ProcessAMDGPU::%s() failed to parse module path \" %s\" " ,
240+ __FUNCTION__, module .path .c_str ());
212241 }
213-
214- GPUDynamicLoaderLibraryInfo lib_info;
215- lib_info.pathname = path;
216- lib_info.load = true ;
217- lib_info.load_address = module .base_address ;
218- lib_info.file_offset = file_components.second .first ;
219- lib_info.file_size = file_components.second .second ;
220-
221- LLDB_LOGF (log,
222- " ProcessAMDGPU::%s() adding library: path=%s, addr=0x%" PRIx64
223- " , offset=%" PRIu64 " , size=%" PRIu64,
224- __FUNCTION__, lib_info.pathname .c_str (),
225- lib_info.load_address .value (), lib_info.file_offset .value (),
226- lib_info.file_size .value ());
227-
228- response.library_infos .push_back (lib_info);
229242 }
230243 }
231244
0 commit comments