aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/dev/acpica/compiler/aslload.c
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2017-06-01 00:01:19 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2017-06-01 00:01:19 +0000
commitaf051161437e44a6ceabf9e196f0eb8f33d92b86 (patch)
treed4411998414d0b3c9958f926b75c18ee1c445421 /sys/contrib/dev/acpica/compiler/aslload.c
parentbbeb726b93c0bed9eccdbf401f810140809bb989 (diff)
parentc457a42be4fca72c51fdca569271b62213d01a37 (diff)
downloadsrc-af051161437e44a6ceabf9e196f0eb8f33d92b86.tar.gz
src-af051161437e44a6ceabf9e196f0eb8f33d92b86.zip
Merge ACPICA 20170531.
Notes
Notes: svn path=/head/; revision=319365
Diffstat (limited to 'sys/contrib/dev/acpica/compiler/aslload.c')
-rw-r--r--sys/contrib/dev/acpica/compiler/aslload.c90
1 files changed, 80 insertions, 10 deletions
diff --git a/sys/contrib/dev/acpica/compiler/aslload.c b/sys/contrib/dev/acpica/compiler/aslload.c
index c304f30e2e2b..1e3deeea541d 100644
--- a/sys/contrib/dev/acpica/compiler/aslload.c
+++ b/sys/contrib/dev/acpica/compiler/aslload.c
@@ -315,13 +315,20 @@ LdLoadFieldElements (
Child->Asl.Value.String);
return (Status);
}
-
- /*
- * The name already exists in this scope
- * But continue processing the elements
- */
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
- Child->Asl.Value.String);
+ else if (Status == AE_ALREADY_EXISTS &&
+ (Node->Flags & ANOBJ_IS_EXTERNAL))
+ {
+ Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
+ }
+ else
+ {
+ /*
+ * The name already exists in this scope
+ * But continue processing the elements
+ */
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
+ Child->Asl.Value.String);
+ }
}
else
{
@@ -458,12 +465,30 @@ LdNamespace1Begin (
ACPI_PARSE_OBJECT *Arg;
UINT32 i;
BOOLEAN ForceNewScope = FALSE;
+ ACPI_OWNER_ID OwnerId = 0;
ACPI_FUNCTION_NAME (LdNamespace1Begin);
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
Op, Op->Asl.ParseOpName));
+ if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
+ {
+ /*
+ * Allocate an OwnerId for this block. This helps identify the owners
+ * of each namespace node. This is used in determining whether if
+ * certain external declarations cause redefinition errors.
+ */
+ Status = AcpiUtAllocateOwnerId (&OwnerId);
+ WalkState->OwnerId = OwnerId;
+ if (ACPI_FAILURE (Status))
+ {
+ AslCoreSubsystemError (Op, Status,
+ "Failure to allocate owner ID to this definition block.", FALSE);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
/*
* We are only interested in opcodes that have an associated name
* (or multiple names)
@@ -778,7 +803,9 @@ LdNamespace1Begin (
{
/*
* Allow one create on an object or segment that was
- * previously declared External
+ * previously declared External only if WalkState->OwnerId and
+ * Node->OwnerId are found in different tables (meaning that
+ * they have differnt OwnerIds).
*/
Node->Flags &= ~ANOBJ_IS_EXTERNAL;
Node->Type = (UINT8) ObjectType;
@@ -795,6 +822,12 @@ LdNamespace1Begin (
}
Status = AE_OK;
+
+ if (Node->OwnerId == WalkState->OwnerId)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName);
+ }
}
else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
@@ -802,15 +835,52 @@ LdNamespace1Begin (
/*
* Allow externals in same scope as the definition of the
* actual object. Similar to C. Allows multiple definition
- * blocks that refer to each other in the same file.
+ * blocks that refer to each other in the same file. However,
+ * do not allow name declaration and an external declaration
+ * within the same table. This is considered a re-declaration.
*/
Status = AE_OK;
+
+ if (Node->OwnerId == WalkState->OwnerId)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName);
+ }
}
else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
(ObjectType == ACPI_TYPE_ANY))
{
- /* Allow update of externals of unknown type. */
+ /*
+ * Allow update of externals of unknown type.
+ * In the case that multiple definition blocks are being
+ * parsed, updating the OwnerId allows enables subsequent calls
+ * of this method to understand which table the most recent
+ * external declaration was seen. Without this OwnerId update,
+ * code like the following is allowed to compile:
+ *
+ * DefinitionBlock("externtest.aml", "DSDT", 0x02, "Intel", "Many", 0x00000001)
+ * {
+ * External(ERRS,methodobj)
+ * Method (MAIN)
+ * {
+ * Name(NUM2, 0)
+ * ERRS(1,2,3)
+ * }
+ * }
+ *
+ * DefinitionBlock("externtest.aml", "SSDT", 0x02, "Intel", "Many", 0x00000001)
+ * {
+ * if (0)
+ * {
+ * External(ERRS,methodobj)
+ * }
+ * Method (ERRS,3)
+ * {}
+ *
+ * }
+ */
+ Node->OwnerId = WalkState->OwnerId;
if (AcpiNsOpensScope (ActualObjectType))
{