2010-06-09 00:52:24 +08:00
|
|
|
//===-- UUID.cpp ------------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-03-04 09:28:55 +08:00
|
|
|
#include "lldb/Utility/UUID.h"
|
|
|
|
|
2017-03-04 09:30:05 +08:00
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
|
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
#include "llvm/Support/Format.h"
|
2017-03-04 09:30:05 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// C Includes
|
2010-06-10 03:36:54 +08:00
|
|
|
#include <ctype.h>
|
2016-09-07 04:57:50 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2010-06-10 03:36:54 +08:00
|
|
|
|
2018-06-21 23:24:39 +08:00
|
|
|
using namespace lldb_private;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
// Whether to put a separator after count uuid bytes.
|
|
|
|
// For the first 16 bytes we follow the traditional UUID format. After that, we
|
|
|
|
// simply put a dash after every 6 bytes.
|
|
|
|
static inline bool separate(size_t count) {
|
|
|
|
if (count >= 10)
|
|
|
|
return (count - 10) % 6 == 0;
|
|
|
|
|
|
|
|
switch (count) {
|
|
|
|
case 4:
|
|
|
|
case 6:
|
|
|
|
case 8:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
std::string UUID::GetAsString(llvm::StringRef separator) const {
|
2016-09-07 04:57:50 +08:00
|
|
|
std::string result;
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
llvm::raw_string_ostream os(result);
|
|
|
|
|
|
|
|
for (auto B : llvm::enumerate(GetBytes())) {
|
|
|
|
if (separate(B.index()))
|
|
|
|
os << separator;
|
|
|
|
|
|
|
|
os << llvm::format_hex_no_prefix(B.value(), 2, true);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
os.flush();
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UUID::Dump(Stream *s) const {
|
2017-11-28 09:26:07 +08:00
|
|
|
s->PutCString(GetAsString().c_str());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int xdigit_to_int(char ch) {
|
|
|
|
ch = tolower(ch);
|
|
|
|
if (ch >= 'a' && ch <= 'f')
|
|
|
|
return 10 + ch - 'a';
|
|
|
|
return ch - '0';
|
|
|
|
}
|
|
|
|
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
llvm::StringRef
|
|
|
|
UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
|
|
|
|
llvm::SmallVectorImpl<uint8_t> &uuid_bytes,
|
|
|
|
uint32_t num_uuid_bytes) {
|
|
|
|
uuid_bytes.clear();
|
2016-11-17 09:37:42 +08:00
|
|
|
while (!p.empty()) {
|
|
|
|
if (isxdigit(p[0]) && isxdigit(p[1])) {
|
|
|
|
int hi_nibble = xdigit_to_int(p[0]);
|
|
|
|
int lo_nibble = xdigit_to_int(p[1]);
|
|
|
|
// Translate the two hex nibble characters into a byte
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
|
2016-11-17 09:37:42 +08:00
|
|
|
|
|
|
|
// Skip both hex digits
|
|
|
|
p = p.drop_front(2);
|
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Increment the byte that we are decoding within the UUID value and
|
|
|
|
// break out if we are done
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
if (uuid_bytes.size() == num_uuid_bytes)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
2016-11-17 09:37:42 +08:00
|
|
|
} else if (p.front() == '-') {
|
|
|
|
// Skip dashes
|
|
|
|
p = p.drop_front();
|
|
|
|
} else {
|
|
|
|
// UUID values can only consist of hex characters and '-' chars
|
|
|
|
break;
|
2013-05-24 04:57:03 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-11-17 09:37:42 +08:00
|
|
|
return p;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2017-05-12 13:49:54 +08:00
|
|
|
size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) {
|
|
|
|
llvm::StringRef p = str;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Skip leading whitespace characters
|
2016-11-17 09:37:42 +08:00
|
|
|
p = p.ltrim();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
llvm::SmallVector<uint8_t, 20> bytes;
|
2016-11-17 09:37:42 +08:00
|
|
|
llvm::StringRef rest =
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// If we successfully decoded a UUID, return the amount of characters that
|
|
|
|
// were consumed
|
UUID: Add support for arbitrary-sized module IDs
Summary:
The data structure is optimized for the case where the UUID size is <=
20 bytes (standard length emitted by the GNU linkers), but larger sizes
are also possible.
I've modified the string conversion function to support the new sizes as
well. For standard UUIDs it maintains the traditional formatting
(4-2-2-2-6). If a UUID is shorter, we just cut this sequence short, and
for longer UUIDs it will just repeat the last 6-byte block as long as
necessary.
I've also modified ObjectFileELF to take advantage of the new UUIDs and
avoid manually padding the UUID to 16 bytes. While there, I also made
sure the computed UUID does not depend on host endianness.
Reviewers: clayborg, lemo, sas, davide, espindola
Subscribers: emaste, arichardson, lldb-commits
Differential Revision: https://reviews.llvm.org/D48633
llvm-svn: 335963
2018-06-29 19:20:29 +08:00
|
|
|
if (bytes.size() == num_uuid_bytes) {
|
|
|
|
*this = fromData(bytes);
|
2017-05-12 13:49:54 +08:00
|
|
|
return str.size() - rest.size();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Else return zero to indicate we were not able to parse a UUID value
|
|
|
|
return 0;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|