[gdb/symtab] Add producer_is_gas

Add producer_is_gas, a generic way to get the gas version from the
producer string.

Tested on x86_64-linux.
This commit is contained in:
Tom de Vries 2023-11-01 00:33:12 +01:00
parent 87e3cc466e
commit 98ef1d81d6
3 changed files with 63 additions and 2 deletions

View File

@ -11250,8 +11250,8 @@ check_producer (struct dwarf2_cu *cu)
cu->producer_is_codewarrior = true;
else if (producer_is_clang (cu->producer, &major, &minor))
cu->producer_is_clang = true;
else if (startswith (cu->producer, "GNU AS 2.39.0"))
cu->producer_is_gas_2_39 = true;
else if (producer_is_gas (cu->producer, &major, &minor))
cu->producer_is_gas_2_39 = major == 2 && minor == 39;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version

View File

@ -81,6 +81,45 @@ producer_is_gcc (const char *producer, int *major, int *minor)
/* See producer.h. */
bool
producer_is_gas (const char *producer, int *major, int *minor)
{
if (producer == nullptr)
{
/* No producer, don't know. */
return false;
}
/* Detect prefix. */
const char prefix[] = "GNU AS ";
if (!startswith (producer, prefix))
{
/* Producer is not gas. */
return false;
}
/* Skip prefix. */
const char *cs = &producer[strlen (prefix)];
/* Ensure that major/minor are not nullptrs. */
int maj, min;
if (major == nullptr)
major = &maj;
if (minor == nullptr)
minor = &min;
int scanned = sscanf (cs, "%d.%d", major, minor);
if (scanned != 2)
{
/* Unable to scan major/minor version. */
return false;
}
return true;
}
/* See producer.h. */
bool
producer_is_icc_ge_19 (const char *producer)
{
@ -251,6 +290,23 @@ Version 18.0 Beta";
SELF_CHECK (!producer_is_gcc (flang_llvm_exp, &major, &minor));
SELF_CHECK (producer_is_llvm (flang_llvm_exp));
}
{
static const char gas_exp[] = "GNU AS 2.39.0";
int major = 0, minor = 0;
SELF_CHECK (!producer_is_gcc (gas_exp, &major, &minor));
SELF_CHECK (producer_is_gas (gas_exp, &major, &minor));
SELF_CHECK (major == 2 && minor == 39);
static const char gas_incomplete_exp[] = "GNU AS ";
SELF_CHECK (!producer_is_gas (gas_incomplete_exp, &major, &minor));
SELF_CHECK (!producer_is_gcc (gas_incomplete_exp, &major, &minor));
static const char gas_incomplete_exp_2[] = "GNU AS 2";
SELF_CHECK (!producer_is_gas (gas_incomplete_exp_2, &major, &minor));
SELF_CHECK (!producer_is_gcc (gas_incomplete_exp_2, &major, &minor));
}
}
}
}

View File

@ -30,6 +30,11 @@ extern int producer_is_gcc_ge_4 (const char *producer);
is NULL or it isn't GCC. */
extern int producer_is_gcc (const char *producer, int *major, int *minor);
/* Returns nonzero if the given PRODUCER string is GAS and sets the MAJOR
and MINOR versions when not NULL. Returns zero if the given PRODUCER
is NULL or it isn't GAS. */
bool producer_is_gas (const char *producer, int *major, int *minor);
/* Check for Intel compilers >= 19.0. */
extern bool producer_is_icc_ge_19 (const char *producer);