diff options
Diffstat (limited to 'scripts/gendwarfksyms/kabi.c')
-rw-r--r-- | scripts/gendwarfksyms/kabi.c | 143 |
1 files changed, 90 insertions, 53 deletions
diff --git a/scripts/gendwarfksyms/kabi.c b/scripts/gendwarfksyms/kabi.c index 66f01fcd1607..b3ade713778f 100644 --- a/scripts/gendwarfksyms/kabi.c +++ b/scripts/gendwarfksyms/kabi.c @@ -54,11 +54,27 @@ */ #define KABI_RULE_TAG_ENUMERATOR_VALUE "enumerator_value" +/* + * Rule: byte_size + * - For the fqn_field in the target field, set the byte_size + * attribute to the value in the value field. + */ +#define KABI_RULE_TAG_BYTE_SIZE "byte_size" + +/* + * Rule: type_string + * - For the type reference in the fqn field, use the type string + * in the value field. + */ +#define KABI_RULE_TAG_TYPE_STRING "type_string" + enum kabi_rule_type { KABI_RULE_TYPE_UNKNOWN, KABI_RULE_TYPE_DECLONLY, KABI_RULE_TYPE_ENUMERATOR_IGNORE, KABI_RULE_TYPE_ENUMERATOR_VALUE, + KABI_RULE_TYPE_BYTE_SIZE, + KABI_RULE_TYPE_TYPE_STRING, }; #define RULE_HASH_BITS 7 @@ -127,6 +143,14 @@ void kabi_read_rules(int fd) .type = KABI_RULE_TYPE_ENUMERATOR_VALUE, .tag = KABI_RULE_TAG_ENUMERATOR_VALUE, }, + { + .type = KABI_RULE_TYPE_BYTE_SIZE, + .tag = KABI_RULE_TAG_BYTE_SIZE, + }, + { + .type = KABI_RULE_TYPE_TYPE_STRING, + .tag = KABI_RULE_TAG_TYPE_STRING, + }, }; if (!stable) @@ -222,33 +246,55 @@ void kabi_read_rules(int fd) check(elf_end(elf)); } -bool kabi_is_declonly(const char *fqn) +static char *get_enumerator_target(const char *fqn, const char *field) +{ + char *target = NULL; + + if (asprintf(&target, "%s %s", fqn, field) < 0) + error("asprintf failed for '%s %s'", fqn, field); + + return target; +} + +static struct rule *find_rule(enum kabi_rule_type type, const char *target) { struct rule *rule; if (!stable) - return false; - if (!fqn || !*fqn) - return false; + return NULL; + if (!target || !*target) + return NULL; hash_for_each_possible(rules, rule, hash, - rule_values_hash(KABI_RULE_TYPE_DECLONLY, fqn)) { - if (rule->type == KABI_RULE_TYPE_DECLONLY && - !strcmp(fqn, rule->target)) - return true; + rule_values_hash(type, target)) { + if (rule->type == type && !strcmp(target, rule->target)) + return rule; } - return false; + return NULL; } -static char *get_enumerator_target(const char *fqn, const char *field) +static struct rule *find_enumerator_rule(enum kabi_rule_type type, + const char *fqn, const char *field) { - char *target = NULL; + struct rule *rule; + char *target; - if (asprintf(&target, "%s %s", fqn, field) < 0) - error("asprintf failed for '%s %s'", fqn, field); + if (!stable) + return NULL; + if (!fqn || !*fqn || !field || !*field) + return NULL; - return target; + target = get_enumerator_target(fqn, field); + rule = find_rule(type, target); + + free(target); + return rule; +} + +bool kabi_is_declonly(const char *fqn) +{ + return !!find_rule(KABI_RULE_TYPE_DECLONLY, fqn); } static unsigned long get_ulong_value(const char *value) @@ -267,58 +313,49 @@ static unsigned long get_ulong_value(const char *value) bool kabi_is_enumerator_ignored(const char *fqn, const char *field) { - bool match = false; - struct rule *rule; - char *target; - - if (!stable) - return false; - if (!fqn || !*fqn || !field || !*field) - return false; + return !!find_enumerator_rule(KABI_RULE_TYPE_ENUMERATOR_IGNORE, fqn, + field); +} - target = get_enumerator_target(fqn, field); +bool kabi_get_enumerator_value(const char *fqn, const char *field, + unsigned long *value) +{ + struct rule *rule; - hash_for_each_possible( - rules, rule, hash, - rule_values_hash(KABI_RULE_TYPE_ENUMERATOR_IGNORE, target)) { - if (rule->type == KABI_RULE_TYPE_ENUMERATOR_IGNORE && - !strcmp(target, rule->target)) { - match = true; - break; - } + rule = find_enumerator_rule(KABI_RULE_TYPE_ENUMERATOR_VALUE, fqn, + field); + if (rule) { + *value = get_ulong_value(rule->value); + return true; } - free(target); - return match; + return false; } -bool kabi_get_enumerator_value(const char *fqn, const char *field, - unsigned long *value) +bool kabi_get_byte_size(const char *fqn, unsigned long *value) { - bool match = false; struct rule *rule; - char *target; - if (!stable) - return false; - if (!fqn || !*fqn || !field || !*field) - return false; + rule = find_rule(KABI_RULE_TYPE_BYTE_SIZE, fqn); + if (rule) { + *value = get_ulong_value(rule->value); + return true; + } - target = get_enumerator_target(fqn, field); + return false; +} - hash_for_each_possible(rules, rule, hash, - rule_values_hash(KABI_RULE_TYPE_ENUMERATOR_VALUE, - target)) { - if (rule->type == KABI_RULE_TYPE_ENUMERATOR_VALUE && - !strcmp(target, rule->target)) { - *value = get_ulong_value(rule->value); - match = true; - break; - } +bool kabi_get_type_string(const char *type, const char **str) +{ + struct rule *rule; + + rule = find_rule(KABI_RULE_TYPE_TYPE_STRING, type); + if (rule) { + *str = rule->value; + return true; } - free(target); - return match; + return false; } void kabi_free(void) |